/* #include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    const char *name = (const char *)args;
    while (1)
    {
        printf("I am the new thread, name: %s\n", name);
        sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t tid;
    // 创建一个新线程，让它执行 thread_run 函数
    pthread_create(&tid, NULL, thread_run, (void *)"thread-1");

    while (1)
    {
        printf("I am the main thread\n");
        sleep(1);
    }

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    printf("New thread running...\n");
    sleep(1); // 运行1秒
    int a = 10;
    a = a / 0; // 触发致命错误
    printf("This line will never be printed.\n");
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, thread_run, NULL);

    while (1)
    {
        printf("Main thread is still alive...\n");
        sleep(1);
    }
    return 0;
} */
/*
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    const char *name = (const char *)args;
    int i = 0;
    for (i = 0; i < 5; i++)
    {
        printf("I am new thread, name: %s, loop %d\n", name, i);
        sleep(1);
    }
    return (void *)100; // 线程退出，返回一个值
}

int main()
{
    pthread_t tid;
    char thread_name[] = "thread-1";

    // 1. 创建线程，并传递参数 "thread-1"
    pthread_create(&tid, NULL, thread_run, (void *)thread_name);

    printf("Main thread created a new thread [%lu]\n", tid);

    // 2. 等待新线程结束，并获取其返回值
    void *ret = NULL;
    pthread_join(tid, &ret);

    printf("Main thread joined. New thread exited with code: %ld\n", (long)ret);

    return 0;
} */

/* #include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    const char *name = (const char *)args;

    // 3. 新线程获取自身线程ID
    pthread_t self_tid = pthread_self();
    printf("I am new thread, name: %s, thread ID [%lu]\n", name, self_tid);
    sleep(1);

    return (void *)100; // 线程退出，返回一个值
}

int main()
{
    pthread_t tid;
    char thread_name[] = "thread-1";

    // 1. 创建线程，并传递参数 "thread-1"
    pthread_create(&tid, NULL, thread_run, (void *)thread_name);

    printf("Main thread created a new thread [%lu]\n", tid);

    // 2. 等待新线程结束，并获取其返回值
    void *ret = NULL;
    pthread_join(tid, &ret);

    printf("Main thread joined. New thread exited with code: %ld\n", (long)ret);

    return 0;
} */

/* #include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>

// 新线程
void *Routine(void *arg)
{
    char *msg = (char *)arg;
    while (1)
    {
        printf("I am %s...pid: %d, ppid: %d, tid: %lu\n", msg, getpid(), getppid(), pthread_self());
        sleep(1);
    }
    return (void *)0;
}

// 主进程
int main()
{
    pthread_t tid[5];

    for (int i = 0; i < 5; i++)
    {
        char *buffer = (char *)malloc(64);
        sprintf(buffer, "thread %d", i);
        pthread_create(&tid[i], NULL, Routine, buffer);
        printf("%s tid is %lu\n", buffer, tid[i]);
    }

    printf("I am main thread...pid: %d, ppid: %d, tid: %lu\n", getpid(), getppid(), pthread_self());

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void *infinite_loop(void *args)
{
    printf("New thread starting its infinite loop...\n");
    while (1)
    {
        // 在实际应用中，这里应该是一个"取消点"，例如 read, write, sleep
        // sleep() 是一个取消点，允许线程响应取消请求
        sleep(1);
    }

    // 这行代码永远不会执行
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, infinite_loop, NULL);

    // 让新线程先运行3秒
    printf("Main thread: letting the new thread run for 3 seconds.\n");
    sleep(3);

    // 发送取消请求
    printf("Main thread: sending a cancellation request...\n");
    pthread_cancel(tid);

    // 等待被取消的线程，并获取其退出状态
    void *ret_val = NULL;
    pthread_join(tid, &ret_val);

    if (ret_val == PTHREAD_CANCELED)
    {
        printf("Main thread: Confirmed, the new thread was canceled. Exit code: %ld\n", (long)ret_val);
    }
    else
    {
        printf("Main thread: The new thread exited normally.\n");
    }

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    // 新线程开始工作
    printf(" -> New Thread: Starting my work...\n");
    for (int i = 1; i <= 3; i++)
    {
        printf(" -> New Thread: Working... (%d/3)\n", i);
        sleep(1);
    }

    // 任务完成, 通过 return 返回退出状态码 100。
    printf(" -> New Thread: Work complete. Returning with exit code 100.\n");
    return (void *)100;
}

int main()
{
    pthread_t tid;
    void *retval = NULL;

    // 创建新线程
    printf("Main Thread: Creating a new thread.\n");
    pthread_create(&tid, NULL, thread_run, NULL);

    // 主线程等待新线程
    printf("Main Thread: Waiting for the new thread to finish...\n");
    pthread_join(tid, &retval);

    // 新线程结束，主线程通过 pthread_join 捕获返回值
    printf("Main Thread: Joined with the new thread.\n");
    printf("Main Thread: The captured return value is %ld.\n", (long)retval);

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <pthread.h>

void *thread_run(void *args)
{
    printf(" -> New Thread: Starting my work...\n");
    sleep(2);

    int error_condition = 1; // 模拟一个错误条件
    if (error_condition)
    {
        printf(" -> New Thread: An error occurred! Exiting early with code 200.\n");
        // 在函数中间提前退出，效果等同于 return (void*)200;
        pthread_exit((void *)200);
    }

    // 因为 pthread_exit 被调用，下面的代码将永远不会被执行
    printf(" -> New Thread: This line will never be printed.\n");
    return (void *)0;
}

int main()
{
    pthread_t tid;
    void *retval = NULL;

    // 创建新线程
    printf("Main Thread: Creating a new thread.\n");
    pthread_create(&tid, NULL, thread_run, NULL);

    // 主线程等待新线程
    printf("Main Thread: Waiting for the new thread to finish...\n");
    pthread_join(tid, &retval);

    // 新线程结束，主线程通过 pthread_join 捕获返回值
    printf("Main Thread: Joined with the new thread.\n");
    printf("Main Thread: The captured return value is %ld.\n", (long)retval);

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <stdlib.h> // for exit()
#include <pthread.h>

void *thread_run(void *args)
{
    printf(" -> New Thread: I will terminate the whole process in 3 seconds.\n");
    sleep(3);
    printf(" -> New Thread: Calling exit(13) NOW!\n");

    // 这是一个错误的做法！它会杀死整个进程！
    exit(13);

    // 下面的代码永远不会执行
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, thread_run, NULL);

    // 主线程进入自己的循环，它期望能一直运行
    for (int i = 0; i < 10; i++)
    {
        printf("Main Thread: I am still alive... (%d/10)\n", i + 1);
        sleep(1);
    }

    printf("Main Thread: This line will never be reached.\n");
    pthread_join(tid, NULL); // 也永远不会执行到这里

    return 0;
} */

/* #include <stdio.h>
#include <unistd.h>
#include <string.h> // for strerror()
#include <errno.h>  // for errno values
#include <pthread.h>

void *worker_thread_run(void *args)
{
    // 新线程开始工作
    printf(" -> Worker Thread: Starting my 5-second task.\n");
    sleep(5);

    // 新线程工作完成，结束线程
    printf(" -> Worker Thread: Task finished, I will now exit and self-release.\n");
    return NULL;
}

int main()
{
    // 创建新线程
    pthread_t tid;
    pthread_create(&tid, NULL, worker_thread_run, NULL);
    printf("Main Thread: Created a worker thread.\n");

    // 立即分离新线程
    printf("Main Thread: Detaching the worker thread...\n");
    pthread_detach(tid);

    // 主线程继续做自己的事情，这里用 sleep 模拟
    // 确保主线程比工作线程活得长，以便观察
    sleep(7);

    // 现在尝试去 join 一个已经被分离的线程
    printf("Main Thread: Attempting to join the detached thread...\n");
    int join_ret = pthread_join(tid, NULL);

    if (join_ret != 0)
    {
        // 预期返回：EINVAL (22) is "Invalid argument"
        printf("Main Thread: As expected, pthread_join failed.\n");
        printf("Main Thread: Error code %d means: %s\n", join_ret, strerror(join_ret));
    }
    else
    {
        printf("Main Thread: This should not happen!\n");
    }

    printf("Main Thread: Program finished.\n");
    return 0;
} */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

void *worker_thread_run(void *args)
{
    // 线程获取自己的ID
    pthread_t self_id = pthread_self();
    // 线程自己分离自己
    pthread_detach(self_id);
    printf(" -> Worker Thread [%lu]: I have detached myself.\n", self_id);

    // 新线程开始工作
    printf(" -> Worker Thread: Starting my 5-second task.\n");
    sleep(5);

    // 工作完成结束线程
    printf(" -> Worker Thread: Task finished, exiting.\n");
    return NULL;
}

int main()
{
    // 创建新线程
    pthread_t tid;
    pthread_create(&tid, NULL, worker_thread_run, NULL);
    printf("Main Thread: Created a worker thread [%lu].\n", tid);

    // 等待足够长的时间，以确保工作线程已经把自己分离了
    sleep(1);

    // 主进程尝试捕获新线程
    printf("Main Thread: Attempting to join the (now detached) thread...\n");
    int join_ret = pthread_join(tid, NULL);

    if (join_ret != 0)
    {
        // 成功捕获
        printf("Main Thread: As expected, pthread_join failed.\n");
        printf("Main Thread: Error code %d means: %s\n", join_ret, strerror(join_ret));
    }

    // 主线程需要存活，否则进程退出，所有线程都会被杀死
    sleep(6);
    printf("Main Thread: Program finished.\n");
    return 0;
}